package com.lry.app.service.impl;

import com.lry.app.ExampleStateMachine;
import com.lry.app.service.KvService;
import com.lry.client.RpcClient;
import com.lry.client.RpcProxy;
import com.lry.core.Peer;
import com.lry.core.RaftNode;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;

@Slf4j
public class KvServiceImpl implements KvService {

    private RaftNode raftNode;

    public KvServiceImpl(RaftNode raftNode){
        this.raftNode = raftNode;
    }

    @Override
    public String set(String key, String value) {
        if(null==raftNode.getLeaderId()){
            log.info("暂时还没有选举出leader，raft处于不可用状态，请稍后重试");
            return null;
        }

        //如果自己不是leader，需要转发给leader处理写请求
        if(raftNode.getLeaderId().intValue()!=raftNode.getServerId()){
            Peer leader = raftNode.getServerId2Peer().get(raftNode.getLeaderId());
            RpcClient rpcClient = new RpcClient(leader.getServer().getHost(),leader.getServer().getPort());
            KvService kvService = RpcProxy.getProxy(rpcClient,KvService.class);
            return kvService.set(key,value);
        }

        String command = "set "+key+" "+value;
        //自己是leader, 自己落盘，并且同步给其他从节点，有超过一半的节点落盘成功，则返回成功，否则失败
        return new String(raftNode.replicate(command.getBytes(StandardCharsets.UTF_8)));
    }

    @Override
    public String get(String key) {
        return new String(raftNode.getStateMachine().get(key.getBytes()));
    }

}
